#include "C_SQLite.h"
#include "C_SQLiteQuery.h"

C_SQLite::C_SQLite()
{
	m_dbOpen = false;
}


C_SQLite::~C_SQLite()
{
	m_dbOpen = false;
	SQLE(sqlite3_close(m_instance));
}

void C_SQLite::createIfNotExist(std::string filename, C_SQLiteQuery* query)
{
	//open for creating
	SQLE(sqlite3_open(filename.c_str(), &m_instance));

	std::string testQuery = "SELECT name FROM sqlite_master WHERE tbl_name = '" + query->tableName() + "' AND type='table'";

	sqlite3_stmt *statement;
	this->execStmt(testQuery, statement);
	int res = sqlite3_step(statement);
	
	if (res != SQLITE_ROW)
	{
		exec(query->execToStr());
	}
	m_dbOpen = true;
}

int C_SQLite::callback(void *pArg, int argc, char **argv, char **columnNames)
{
	return 0;
}

void C_SQLite::exec(std::string query, int count)
{
	sqlite3_stmt *statement;
	SQLE(sqlite3_prepare_v2(m_instance, query.c_str(), strlen(query.c_str())+1, &statement, NULL));
	for (int i = 0; i < count; i++)
		int res = sqlite3_step(statement);
	sqlite3_finalize(statement);
}

void C_SQLite::execStmt(std::string query, sqlite3_stmt* &statement)
{
	SQLE(sqlite3_prepare_v2(m_instance, query.c_str(), -1, &statement, NULL));
}

bool C_SQLite::checkError(int error)
{
	std::string errString = "#SQLITE ERROR: ";
	switch (error)
	{
	case SQLITE_OK:
	{
							return true;
							break;
	}
	case SQLITE_ERROR:
	{
							throw std::runtime_error(errString += "#SQLITE_ERROR: - SQL error or missing database\n");
							break;
	}
	case SQLITE_INTERNAL:
	{
							throw std::runtime_error(errString += "#SQLITE_INTERNAL: - An internal logic error in SQLite\n");
							break;
	}
	case SQLITE_PERM:
	{
							throw std::runtime_error(errString += "#SQLITE_PERM: - Access permission denied\n");
							break;
	}
	case SQLITE_ABORT:
	{
							throw std::runtime_error(errString += "#SQLITE_ABORT: - Callback routine requested an abort\n");
							break;
	}
	case SQLITE_BUSY:
	{
							throw std::runtime_error(errString += "#SQLITE_BUSY: - The database file is locked\n");
							break;
	}
	case SQLITE_LOCKED:
	{
						throw std::runtime_error(errString += "#SQLITE_LOCKED: - A table in the database is locked\n");
						break;
	}
	case SQLITE_NOMEM:
	{
						throw std::runtime_error(errString += "#SQLITE_NOMEM: - A malloc() failed\n");
						break;
	}
	case SQLITE_READONLY:
	{
						throw std::runtime_error(errString += "#SQLITE_READONLY: - Attempt to write a readonly database\n");
						break;
	}
	case SQLITE_INTERRUPT:
	{
							throw std::runtime_error(errString += "#SQLITE_INTERRUPT: - Operation terminated by sqlite_interrupt()\n");
							break;
	}
	case SQLITE_IOERR:
	{
							 throw std::runtime_error(errString += "#SQLITE_IOERR: - Some kind of disk I/O error occurred\n");
							 break;
	}
	case SQLITE_CORRUPT:
	{
							 throw std::runtime_error(errString += "#SQLITE_CORRUPT: - The database disk image is malformed\n");
							 break;
	}
	case SQLITE_NOTFOUND:
	{
							 throw std::runtime_error(errString += "#SQLITE_NOTFOUND: - (Internal Only) Table or record not found\n");
							 break;
	}
	case SQLITE_FULL:
	{
							 throw std::runtime_error(errString += "#SQLITE_FULL: - Insertion failed because database is full\n");
							 break;
	}
	case SQLITE_CANTOPEN:
	{
						throw std::runtime_error(errString += "#SQLITE_CANTOPEN: - Unable to open the database file\n");
						break;
	}
	case SQLITE_PROTOCOL:
	{
						throw std::runtime_error(errString += "#SQLITE_PROTOCOL: - Database lock protocol error\n");
						break;
	}
	case SQLITE_EMPTY:
	{
						throw std::runtime_error(errString += "#SQLITE_EMPTY: - (Internal Only) Database table is empty\n");
						break;
	}
	case SQLITE_SCHEMA:
	{
						throw std::runtime_error(errString += "#SQLITE_SCHEMA: - The database schema changed\n");
						break;
	}
	case SQLITE_TOOBIG:
	{
						throw std::runtime_error(errString += "#SQLITE_TOOBIG: - Too much data for one row of a table\n");
						break;
	}
	case SQLITE_CONSTRAINT:
	{
						throw std::runtime_error(errString += "#SQLITE_CONSTRAINT: - Abort due to constraint violation\n");
						break;
	}
	case SQLITE_MISMATCH:
	{
							  throw std::runtime_error(errString += "#SQLITE_MISMATCH: - Data type mismatch\n");
							  break;
	}
	case SQLITE_MISUSE:
	{
							  throw std::runtime_error(errString += "#SQLITE_MISUSE: - Library used incorrectly\n");
							  break;
	}
	case SQLITE_NOLFS:
	{
							  throw std::runtime_error(errString += "#SQLITE_NOLFS: - Uses OS features not supported on host\n");
							  break;
	}
	case SQLITE_AUTH:
	{
							  throw std::runtime_error(errString += "#SQLITE_AUTH: - Authorization denied\n");
							  break;
	}
	case SQLITE_ROW:
	{
							  return true;
							  break;
	}
	case SQLITE_DONE:
	{
							  return true;
							  break;
	}
	default:
		break;
	}
}
